using System;
using System.Collections.Generic;
using UnityEngine;
namespace NL.Advanced
{
    public enum TargetCollectTopmodel
    {

        /// <summary>
        /// 无算法 根据运行时情况
        /// </summary>
        None = 0,



        /// <summary>
        /// 距离：data>0 从近到远；data<0 从远到近。
        /// </summary>
        DistanceNear = 1,

        /// <summary>
        /// 到达目标平面得距离......
        /// </summary>
        Arriving=5,

        /// <summary>
        /// 剩余血量：data>0 从少到多；data<0 从多到少。（数值一样看距离）
        /// </summary>
        LifeLosing = 10,
        /// <summary>
        /// 剩余血量百分比：data>0 从少到多；data<0 从多到少。（数值一样看距离）
        /// </summary>
        LifePercent = 11,

        /// <summary>
        /// 寻找指定类型：与data相同的在前；都符合的看距离近远。
        /// </summary>
        ObjType = 21,

        Random = 99,
    }


    public class CollectorSortCompatr : IComparer<ICombatOwner>
    {
        public ICombatOwner Owner;
        public TargetCollectTopmodel TopModel;
        public int TopmodelData;

        Vector3 _RandomSortDistanceWhere;
        public CollectorSortCompatr(ICombatOwner owner, TargetCollectTopmodel model, int data)
        {
            Owner = owner; TopModel = model; TopmodelData = data;

            if (owner != null)
                _RandomSortDistanceWhere = owner.transform.position
                    + new Vector3(UnityEngine.Random.Range(-20f, 20f), 0, UnityEngine.Random.Range(-20f, 20f));

        }

        /// <summary>
        /// 比较函数，针对不同的TopModel及TopModelData,进行对比。
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public int Compare(ICombatOwner a, ICombatOwner b)
        {
            //GL:增加异常保护
            if (a == null || b == null) return 0;

            float aa, bb = 0;

            //对比值越大得 排序权重高.在队尾
            switch (TopModel)
            {
                case TargetCollectTopmodel.None:
                    return 1;
                case TargetCollectTopmodel.Random:
                    // 使用更加安全的 随机排序..


                    return _CompateDistanceUseRand(a, b);


                case TargetCollectTopmodel.DistanceNear: // 距离近的

                    return (TopmodelData > 0 ? 1 : -1) * _CompateDistance(a, b);


                case TargetCollectTopmodel.Arriving:// 子考虑Z轴得距离.到达一个Z轴平面
                    return (TopmodelData > 0 ? 1 : -1) * _CompateDistance_Z(a, b);


                case TargetCollectTopmodel.LifeLosing:// 丢失血量多得...
                    aa = a.HPMax - a.HP;
                    bb = b.HPMax - b.HP;
                    if (aa == bb)
                        return (TopmodelData > 0 ? 1 : -1) * _CompateDistance(a, b);
                    else
                        return (TopmodelData > 0 ? 1 : -1) * (aa < bb ? 1 : -1);
                case TargetCollectTopmodel.LifePercent: // 血量饱满得 n%...

                    aa = a.HPPrecent;
                    bb = b.HPPrecent;
                    if (aa == bb)
                        return (TopmodelData > 0 ? 1 : -1) * _CompateDistance(a, b);
                    else
                        return (TopmodelData > 0 ? 1 : -1) * (aa < bb ? 1 : -1);
                case TargetCollectTopmodel.ObjType:
                    short tx = (short)a.ObjType;
                    short ty = (short)b.ObjType;

                    if (tx == ty && tx == TopmodelData)
                        return _CompateDistance(a, b);
                    else if (tx == TopmodelData)
                        return -1;
                    else
                        return 0;
            }

            return 0;
        }

        int _CompateDistance(ICombatOwner a, ICombatOwner b)
        {
            if (a != null && b != null && Owner != null)
            {
                float xx = Vector3.Distance(Owner.transform.position, a.transform.position);
                float yy = Vector3.Distance(Owner.transform.position, b.transform.position);

                return xx > yy ? 1 : -1;
            }
            return -1;
        }
        int _CompateDistance_Z(ICombatOwner a, ICombatOwner b)
        {
            if (a != null && b != null && Owner != null)
            {
                float xx = Mathf.Abs(Owner.transform.position.z - a.transform.position.z );
                float yy = Mathf.Abs(Owner.transform.position.z - b.transform.position.z);

                return xx > yy ? 1 : -1;
            }
            return -1;
        }

        int _CompateDistanceUseRand(ICombatOwner a, ICombatOwner b)
        {
            if (a != null && b != null && Owner != null)
            {
                float xx = Vector3.Distance(_RandomSortDistanceWhere, a.transform.position);
                float yy = Vector3.Distance(_RandomSortDistanceWhere, b.transform.position);

                return xx > yy ? 1 : -1;
            }
            return -1;
        }
    }

    public class TargetCollectorBase : MonoBehaviour
    {
        public CampType AvilableCamp = CampType.Enemy;



        List<ICombatOwner> __All = new List<ICombatOwner>();



        protected List<ICombatOwner> _All
        {
            get
            {
                NowCount = __All.Count;
                return __All;
            }
        }
        public bool Empty => _All == null || _All.Count < 1;
        public List<ICombatOwner> All => _All;

        [Header("寻敌排序模式.排序")]
        public TargetCollectTopmodel TopModel = TargetCollectTopmodel.DistanceNear;
        public int TopmodelData = 1;



        public int NowCount;

        protected ICombatOwner CombatOwner;

        protected Collider _Collider;


        protected virtual void Awake()
        {

        }

        public void SetOwner(ICombatOwner combatOwner)
        {
            CombatOwner = combatOwner;
        }

        protected virtual bool _IsCollectable(ICombatOwner who)
        {
            return true;
        }

        private bool Check(ICombatOwner who)
        {
            if (who == null)
            {
                return false;
            }

            //判断是否是自己
            if (CombatOwner != null && CombatOwner == who && AvilableCamp != CampType.Self)
            {
                return false;
            }

            //判断忽略..
            if (gameObject.IGNORHas(who.gameObject))
            {
                return false;
            }

            //阵容有效性过滤
            if (!Camp.ISCampOf(AvilableCamp, CombatOwner, who))
            {
                return false;
            }



            if (!_IsCollectable(who))
            {
                return false;
            }

            return true;
        }

        protected void Add(Collider other)
        {
            var who = other.GetComponentInParent<ICombatOwner>();

            if (!Check(who))
            {
                return;
            }


            if (!_All.Contains(who))
            {
                _All.Add(who);
            }
        }
        public float SortDuration = 0.2f;
        float _LastSortime = 0;
        protected void Sort()
        {
            if (Time.time - _LastSortime < SortDuration)
                return;
            _LastSortime = Time.time;
            try
            {


                if (TopModel != TargetCollectTopmodel.None)
                {
                    CollectorSortCompatr Compare = new CollectorSortCompatr(CombatOwner, TopModel, TopmodelData);


                    _All.Sort(Compare);
                }
            }
            catch (Exception ex)
            {
                Debug.LogError($"[TargetCollectorBase.Sort]:Error={ex}");
            }


        }

    }
}
